package system_service

import (
	"errors"
	"fmt"
	"github.com/APP/global"
	"github.com/APP/internal/models"
	"gorm.io/gorm"
	"sort"
)

type RouteService struct{}

// CreateRoute 创建路由
func (s *RouteService) CreateRoute(route *models.SysRoute) (*models.SysRoute, error) {
	// 检查路由名称是否已存在
	var existingRoute models.SysRoute
	if err := global.APP_DB.Where("name = ?", route.Name).First(&existingRoute).Error; err == nil {
		return nil, errors.New("路由名称已存在")
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("检查路由名称失败: %v", err)
	}

	// 如果有父级路由，检查父级路由是否存在
	if route.ParentID != nil {
		var parentRoute models.SysRoute
		if err := global.APP_DB.Where("id = ?", *route.ParentID).First(&parentRoute).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, errors.New("父级路由不存在")
			}
			return nil, fmt.Errorf("检查父级路由失败: %v", err)
		}
	}

	if err := global.APP_DB.Create(route).Error; err != nil {
		return nil, fmt.Errorf("创建路由失败: %v", err)
	}

	return route, nil
}

// UpdateRoute 更新路由
func (s *RouteService) UpdateRoute(route *models.SysRoute) (*models.SysRoute, error) {
	// 检查路由是否存在
	var existingRoute models.SysRoute
	if err := global.APP_DB.Where("id = ?", route.ID).First(&existingRoute).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("路由不存在")
		}
		return nil, fmt.Errorf("查询路由失败: %v", err)
	}

	// 检查路由名称是否与其他路由冲突
	var conflictRoute models.SysRoute
	if err := global.APP_DB.Where("name = ? AND id != ?", route.Name, route.ID).First(&conflictRoute).Error; err == nil {
		return nil, errors.New("路由名称已存在")
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("检查路由名称失败: %v", err)
	}

	// 如果有父级路由，检查父级路由是否存在
	if route.ParentID != nil {
		var parentRoute models.SysRoute
		if err := global.APP_DB.Where("id = ?", *route.ParentID).First(&parentRoute).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, errors.New("父级路由不存在")
			}
			return nil, fmt.Errorf("检查父级路由失败: %v", err)
		}

		// 检查是否形成循环引用
		if *route.ParentID == route.ID {
			return nil, errors.New("不能将自己设置为父级路由")
		}

		// 检查是否将父级设置为自己的子级（递归检查）
		if err := s.checkCircularReference(route.ID, *route.ParentID); err != nil {
			return nil, err
		}
	}

	// 更新字段
	updates := map[string]interface{}{
		"parent_id":       route.ParentID,
		"type":            route.Type,
		"name":            route.Name,
		"title":           route.Title,
		"icon":            route.Icon,
		"active_icon":     route.ActiveIcon,
		"perms":           route.Perms,
		"status":          route.Status,
		"path":            route.Path,
		"active_path":     route.ActivePath,
		"component":       route.Component,
		"link_url":        route.LinkURL,
		"badge_type":      route.BadgeType,
		"badge_content":   route.BadgeContent,
		"badge_style":     route.BadgeStyle,
		"hide_menu":       route.HideMenu,
		"hide_children":   route.HideChildren,
		"hide_breadcrumb": route.HideBreadcrumb,
		"hide_tab":        route.HideTab,
		"keep_alive":      route.KeepAlive,
		"affix":           route.Affix,
		"sort":            route.Sort,
	}

	if err := global.APP_DB.Model(&existingRoute).Updates(updates).Error; err != nil {
		return nil, fmt.Errorf("更新路由失败: %v", err)
	}

	// 重新查询更新后的数据
	if err := global.APP_DB.Where("id = ?", route.ID).First(&existingRoute).Error; err != nil {
		return nil, fmt.Errorf("查询更新后的路由失败: %v", err)
	}

	return &existingRoute, nil
}

// DeleteRoute 删除路由
func (s *RouteService) DeleteRoute(id int) error {
	// 检查路由是否存在
	var route models.SysRoute
	if err := global.APP_DB.Where("id = ?", id).First(&route).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("路由不存在")
		}
		return fmt.Errorf("查询路由失败: %v", err)
	}

	// 检查是否有子路由
	var count int64
	if err := global.APP_DB.Model(&models.SysRoute{}).Where("parent_id = ?", id).Count(&count).Error; err != nil {
		return fmt.Errorf("检查子路由失败: %v", err)
	}

	if count > 0 {
		return errors.New("该路由下还有子路由，无法删除")
	}

	// 删除路由
	if err := global.APP_DB.Delete(&route).Error; err != nil {
		return fmt.Errorf("删除路由失败: %v", err)
	}

	return nil
}

// GetRoute 获取路由详情
func (s *RouteService) GetRoute(id int) (*models.SysRoute, error) {
	var route models.SysRoute
	if err := global.APP_DB.Where("id = ?", id).First(&route).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("路由不存在")
		}
		return nil, fmt.Errorf("查询路由失败: %v", err)
	}

	return &route, nil
}

// GetRouteList 获取路由列表
func (s *RouteService) GetRouteList(page, pageSize int, name, title string, routeType *int, status *int) ([]*models.SysRoute, int64, error) {
	var routes []*models.SysRoute
	var total int64

	// 构建查询条件
	query := global.APP_DB.Model(&models.SysRoute{})

	if name != "" {
		query = query.Where("name LIKE ?", "%"+name+"%")
	}
	if title != "" {
		query = query.Where("title LIKE ?", "%"+title+"%")
	}
	if routeType != nil {
		query = query.Where("type = ?", *routeType)
	}
	if status != nil {
		query = query.Where("status = ?", *status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("查询路由总数失败: %v", err)
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Order("sort ASC, id ASC").Offset(offset).Limit(pageSize).Find(&routes).Error; err != nil {
		return nil, 0, fmt.Errorf("查询路由列表失败: %v", err)
	}

	return routes, total, nil
}

// GetRouteTree 查询并构建路由树（保证顺序稳定）
func (s *RouteService) GetRouteTree() ([]*models.RouteTree, error) {
	var routes []*models.SysRoute

	// 1. 查询数据库，获取所有启用的路由（status=1）
	if err := global.APP_DB.
		Where("status = ?", 1).
		Order("sort ASC, id ASC").
		Find(&routes).Error; err != nil {
		return nil, fmt.Errorf("查询路由列表失败: %v", err)
	}

	// 2. 转换成 map
	routeMap := make(map[int]*models.RouteTree)
	for _, r := range routes {
		routeMap[r.ID] = &models.RouteTree{
			ID:        r.ID,
			Pid:       r.ParentID,
			Name:      r.Name,
			Type:      r.Type,
			Status:    r.Status,
			Path:      r.Path,
			Component: r.Component,
			Perms:     r.Perms,
			Icon:      r.Icon,
			Meta: models.RouteMeta{
				Icon:           r.Icon,
				Title:          r.Title,
				Badge:          r.BadgeContent,
				BadgeType:      r.BadgeType,
				BadgeStyle:     r.BadgeStyle,
				Order:          r.Sort,
				AffixTab:       r.Affix == 1,
				HideMenu:       r.HideMenu == 1,
				HideTab:        r.HideTab == 1,
				KeepAlive:      r.KeepAlive == 1,
				HideChildren:   r.HideChildren == 1,
				HideBreadcrumb: r.HideBreadcrumb == 1,
				IframeSrc:      r.LinkURL,
				Link:           r.LinkURL,
			},
			Children: []*models.RouteTree{},
		}
	}

	// 3. 构造树
	var tree []*models.RouteTree
	for _, node := range routeMap {
		if node.Pid != nil && *node.Pid != 0 {
			if parent, ok := routeMap[*node.Pid]; ok {
				parent.Children = append(parent.Children, node)
			}
		} else {
			tree = append(tree, node)
		}
	}

	// 4. 递归排序
	var sortChildren func(nodes []*models.RouteTree)
	sortChildren = func(nodes []*models.RouteTree) {
		sort.Slice(nodes, func(i, j int) bool {
			if nodes[i].Meta.Order == nodes[j].Meta.Order {
				return nodes[i].ID < nodes[j].ID
			}
			return nodes[i].Meta.Order < nodes[j].Meta.Order
		})
		for _, n := range nodes {
			if len(n.Children) > 0 {
				sortChildren(n.Children)
			}
		}
	}

	sortChildren(tree)

	return tree, nil
}

// checkCircularReference 检查循环引用
func (s *RouteService) checkCircularReference(routeID int, parentID int) error {
	// 递归检查父级路由的父级，看是否会回到当前路由
	var parentRoute models.SysRoute
	if err := global.APP_DB.Where("id = ?", parentID).First(&parentRoute).Error; err != nil {
		return nil // 父级不存在，不会形成循环
	}

	if parentRoute.ParentID != nil {
		if *parentRoute.ParentID == routeID {
			return errors.New("不能形成循环引用")
		}
		return s.checkCircularReference(routeID, *parentRoute.ParentID)
	}

	return nil
}
